home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_02_09
/
2n09034a
< prev
next >
Wrap
Text File
|
1991-08-05
|
16KB
|
470 lines
/**********************************************************
* MENUC.CTL - Allows you to dynamically change your *
* CONFIG.SYS configuration at boot time. *
* *
* Add DEVICE = MENUC.CTL [Mx Tx "Text] to your CONFIG.SYS *
* just ahead of the first group of commands you wish to *
* be able to menu. The x in Tx is the seconds MENUC.CTL *
* will pause for a keystroke before booting normally. *
* x defaults to zero. The x in Mx is the default menu *
* number (1-8) that will be selected in a normal boot. *
* x defaults to one. The text after the " will be the *
* first menu title. All text after the " will be *
* considered part of the title, so it must be the last *
* parameter on the line. The first title can be *
* specified this way, or by putting the following *
* construct immediately after the DEVICE=MENUC.CTL *
* *
* Add DEVICE = MTITLE [Text] to give the boot menu *
* selection a title to put on the screen. Each *
* MTITLE [Text] (up to * eight) will create a new menu *
* selection. *
* *
* Add DEVICE = MENUEND after the last command you wish *
* to be able to menu. MENUEND (like MTITLE) is a dummy *
* device and must appear in CONFIG.SYS in order for *
* MENUC.CTL to operate. *
*********************************************************/
#include "GENERAL.H"
#include "LIB.H"
typedef struct { /* The static part of a device */
BYTE HEADER_LENGTH; /* drivers request header. */
BYTE UNIT_CODE; /* See "Writing MS-DOS Device */
BYTE COMMAND_CODE; /* Drivers" by Robert S. Lai */
WORD STATUS;
double RESERVED;
} RQ_Header;
typedef struct { /* The dynamic part of the */
RQ_Header HEADER; /* "INITIALIZE" request */
BYTE UNITS; /* header to a device driver */
WORD *ENDING_OFFSET;
WORD ENDING_SEGMENT;
char far *ARGUMENTS;
} Init_Header;
typedef struct { /* Structure to keep track */
WORD str_len; /* of location of Config.SYS */
char menu; /* commands to be dealt with */
char far *start;
} Cmd_Rec;
#define Last_Record -1
/* flag to indicate last cmd to process */
#define row_start 9 /* menu start location */
#define col_start 12
#define normal 0x07 /* norman and inverse video */
#define inverse 0x70 /* colors */
BYTE row; /* variables for screen positioning */
BYTE col;
extern WORD MENU_CTL_END;
/* end of resident portion of device driver */
WORD DOS_VERSION;
extern Cmd_Rec _ENDDATA;
/* free memory location for dynamic allocation */
Cmd_Rec near *MyStorage = &_ENDDATA;
/* set pointer to free memory */
Cmd_Rec *Cmds;
/* make it a pointer to Config.Sys commands */
void leave(void); /* device driver exit point */
void clean_up(void);
/* disable non selected Config.SYS commands */
char far *make_coff(char far *Buf);
/* routine to convert non selected Config.Sys *
* commands to BREAK = OFF */
void set_menu(BYTE m); /* setup menu select text */
void display_far(char far *Buf); /* display a far string */
void xlat_ch(char test); /* make control chars visible */
void menu_name(BYTE cmd);
extern Init_Header far *REQUEST_OFFSET;
/* pointer to Device Request Header */
BYTE far *M_Buffer; /* some global variables */
BYTE far *Buf_Start;
BYTE far *Control_End;
BOOL end_found = FALSE;
/* make sure there is a "DEVICE=MENUEND" */
BOOL modified;
/* flag to indicate display screen needs update */
WORD key = 0; /* keeps track of keyboard entry */
WORD junk;
WORD time = 0; /* default time and menu selection */
BYTE menu = 0;
WORD configs; /* number of menus */
char test; /* local char for testing */
char menu_end[] = "DMENUEND";
/* Used to find "DEVICE=MENUEND" */
#define l_menuend sizeof(menu_end) - 1
char bmenu[] = "DMTITLE";
/* Used to find "DEVICE=MTITLE" */
#define l_bmenu sizeof(bmenu) - 1
char menut[7][70];
/* store the titles for upto 8 selections */
// #define Debug = TRUE;
void main(void) {
WORD i;
BYTE j;
BYTE k;
BYTE m;
REQUEST_OFFSET->ENDING_OFFSET = 0;
REQUEST_OFFSET->ENDING_SEGMENT = _CS;
/* tell MS-Dos where our resident portion ends */
M_Buffer = REQUEST_OFFSET->ARGUMENTS;
/* point to rest of Config.Sys Commands */
printstr("MENUC.CTL V1.0 (C) Dec. 6, 1990 by "
"Larry Weaver\n\r$");
/* print a start up line. */
DOS_VERSION = dosversion(); /*get MS-Dos version number*/
if (DOS_VERSION < 0X200) { /* must be greater than 2 */
printstr("Wrong Version of Dos, "
"requires 2X or greater\n\r$");
leave();
}
for (i=0;i < 8;i++) for (j=0;j < 2;j++) menut[i][j] = 0;
/* assume no menu selection titles */
for (;((*M_Buffer != LF) & (*M_Buffer != CR));M_Buffer++){
/* parse MENUC.CTL command line, get default time, menu, *
* and title */
test = *M_Buffer;
#ifdef Debug
xlat_ch(test);
#endif
if (test == '"') { /* see if title 1 */
M_Buffer++;
for (j=1;(*M_Buffer != LF) & (*M_Buffer != CR);
M_Buffer++,j++) {
#ifdef Debug
xlat_ch(*M_Buffer);
#endif
menut[0][j] = *M_Buffer;
}
/* put text in menu array */
menut[0][j] = '\0'; /* add terminating 0 */
menut[0][0] = --j; /* put length in first element */
break;
} else if (test == 'M') { /* see if default menu */
test = *(M_Buffer + 1);
if ((test > '0') & (test < '9')) menu = test - '1';
} else if (test == 'T') { /* see if default time */
test = *(M_Buffer + 1);
if ((test > '/') & (test < ':')) time = test - '0';
}
}
while ((*M_Buffer == CR) | (*M_Buffer == LF)) {
/* go to next command */
#ifdef Debug
xlat_ch(*M_Buffer);
#endif
M_Buffer++;
}
m = 0;
if (cmpsnf(M_Buffer,bmenu,l_bmenu)) {
/* see if next command is "DEVICE=MTITLE", if it is *
* set up title for menu 1 */
#ifdef Debug
display_far(M_Buffer);
#endif
set_menu(m);
}
Buf_Start = M_Buffer;
i = 0;
while (!end_found) {
/* parse rest of Config.Sys commands looking for *
* "DEVICE=MENUEND". Will turn all unrecognized commands *
* into "BREAK=OFF" commands in the process. Also parses *
* rest of menus, and sets up their titles for later *
* selection. */
for (;(*M_Buffer == CR) | (*M_Buffer == LF);M_Buffer++) {
#ifdef Debug
xlat_ch(*M_Buffer);
#endif
}
test = *M_Buffer;
#ifdef Debug
display_far(M_Buffer);
#endif
Control_End = M_Buffer;
Cmds = MyStorage + i;
if (test == 'D') {
end_found = cmpsnf(M_Buffer,menu_end,l_menuend);
/* check for "DEVICE=MENUEND" */
if (end_found) {
make_coff(M_Buffer);
/* deactivate the command line */
Cmds->menu = Last_Record;
break;
} else if (cmpsnf(M_Buffer,bmenu,l_bmenu)) {
/* check for "DEVICE=MTITLE". If too many titles *
* then select menu 1 and leave. */
if (m < 7) {
set_menu(++m);
continue;
} else {
printstr("Too many menu selections. Must be less"
" than 9!\n\rHit any key to continue!$");
junk = get_key();
printstr("\n\r$");
set_menu(++m);
key = EnterKey;
menu = 0;
Cmds->menu = Last_Record;
clean_up();
leave();
}